
#include <math.h>
#include "vec3f.h"

float const PI = 3.1415926535f;

Vec3f::Vec3f() {
	
}

Vec3f::Vec3f(float x, float y, float z) {
	this->x = x;
	this->y = y;
	this->z = z;
}
/*
float &Vec3f::operator[](int index) {
	return v[index];
}

float Vec3f::operator[](int index) const {
	return v[index];
}
*/

Vec3f Vec3f::operator*(float scale) const {
	return Vec3f(x * scale, y * scale, z * scale);
}

Vec3f Vec3f::operator/(float scale) const {
	return Vec3f(x / scale, y / scale, z / scale);
}

Vec3f Vec3f::operator+(const Vec3f &other) const {
	return Vec3f(x + other.x, y + other.y, z + other.z);
}

Vec3f Vec3f::operator-(const Vec3f &other) const {
	return Vec3f(x - other.x, y - other.y, z - other.z);
}

Vec3f Vec3f::operator-() const {
	return Vec3f(-x, -y, -z);
}

const Vec3f &Vec3f::operator*=(float scale) {
	x *= scale;
	y *= scale;
	z *= scale;
	return *this;
}

const Vec3f &Vec3f::operator/=(float scale) {
	x /= scale;
	y /= scale;
	z /= scale;
	return *this;
}

const Vec3f &Vec3f::operator+=(const Vec3f &other) {
	x += other.x;
	y += other.y;
	z += other.z;
	return *this;
}

const Vec3f &Vec3f::operator-=(const Vec3f &other) {
	x -= other.x;
	y -= other.y;
	z -= other.z;
	return *this;
}

float Vec3f::magnitude() const {
	return sqrt(x * x + y * y + z * z);
}

float Vec3f::magnitudeSquared() const {
	return x * x + y * y + z * z;
}

Vec3f Vec3f::normalize() const {
	float m = sqrt(x * x + y * y + z * z);
	return Vec3f(x / m, y / m, z / m);
}

float Vec3f::dot(const Vec3f &other) const {
	return x * other.x + y * other.y + z * other.z;
}

Vec3f Vec3f::cross(const Vec3f &other) const {
	return Vec3f(y * other.z - z * other.y,
				 z * other.x - x * other.z,
				 x * other.y - y * other.x);
}

Vec3f operator*(float scale, const Vec3f &v) {
	return v * scale;
}

Vec3f Vec3f::rotate(Vec3f vec, Vec3f axis, float degrees) {
	axis = axis.normalize();
	float radians = degrees * PI / 180;
	float s = sin(radians);
	float c = cos(radians);
	return vec * c + axis * axis.dot(vec) * (1 - c) + vec.cross(axis) * s;
}